﻿using Styx;
using Styx.Common;
using Styx.Plugins;
using Styx.WoWInternals.WoWObjects;
using System;
using System.Collections.Generic;
using System.Linq;

namespace UseItems
{
    public partial class UseItem : HBPlugin
    {
        #region Overrides of HBPlugin

        /// <summary>
        /// The name of this plugin.
        /// </summary>
        public override string Name
        {
            get { return "UseItems"; }
        }

        /// <summary>
        /// The author of this plugin.
        /// </summary>
        public override string Author
        {
            get { return "Leon Lin"; }
        }

        /// <summary>
        /// The version of the plugin.
        /// </summary>
        public override Version Version
        {
            get { return new Version(1, 0, 0, 0); }
        }

        /// <summary>
        /// The text of the button if the plugin wants it. [Default: "Settings"]
        /// </summary>
        public override string ButtonText
        {
            get { return "Settings"; }
        }

        /// <summary>
        /// Does this plugin want a button? If set to true, the button in the plugin manager will be enabled. [Default: false]
        /// </summary>
        public override bool WantButton
        {
            get { return true; }
        }

        /// <summary>
        /// Called when the user presses the button while having this plugin selected. The plugin can start a thread, show a form, or just do what the hell it wants.
        /// </summary>
        public override void OnButtonPress()
        {
            new FormSettings().ShowDialog();
        }

        private IEnumerable<WoWItem> _usableItems; 
        private static LocalPlayer Me { get { return StyxWoW.Me; } }

        /// <summary>
        /// Called everytime the engine pulses.
        /// </summary>
        public override void Pulse()
        {
            if (!Me.IsAlive || Me.IsGhost || Me.IsOnTransport ||
                Me.OnTaxi || Me.Stunned || Me.Mounted || Me.IsFlying)
            {
                return;
            }

            _usableItems = GetUsableItems();
            if (Me.Combat)
            {
                if (UseItemSettings.Instance.CrystalofInsanity)
                {
                    UseContainerBuffering(UseItemSettings.CRYSTAL_OF_INSANITY);
                }

                if (Me.RealZoneText == UseItemSettings.TIMELESSTILE_ZONE)
                {
                    if (UseItemSettings.Instance.WindfeatherPlume)
                    {
                        UseContainerBuffering(UseItemSettings.WINDFEATHER_PLUME);
                    }

                    if (UseItemSettings.Instance.SingingCrystal)
                    {
                        UseContainerBuffering(UseItemSettings.SINGING_CRYSTAL);
                    }

                    if (UseItemSettings.Instance.BookoftheAges)
                    {
                        UseContainerBuffering(UseItemSettings.BOOK_OF_THE_AGES);
                    }

                    if (UseItemSettings.Instance.DewofEternalMorning)
                    {
                        UseContainerBuffering(UseItemSettings.DEW_OF_ETERNAL_MORNING);
                    }
                }
            }
            else
            {
                if (UseItemSettings.Instance.PlumpIntestines)
                {
                    UseContainerStuff(UseItemSettings.PLUMP_INTESTINES);
                }

                if (UseItemSettings.Instance.StrangeBloatedStomach)
                {
                    UseContainerStuff(UseItemSettings.STRANGE_BLOATED_STOMACH);
                }

                if (UseItemSettings.Instance.SealedCrate)
                {
                    UseContainerStuff(UseItemSettings.SEALED_CRATE);
                }
            }
        }

        public void UseContainerPotion(params string[] item)
        {
            WoWItem potion = FindFirstUsableItemBySpell(item);
            if (potion != null)
            {
                potion.UseContainerItem();
                Log(potion);
            }
        }

        public void UseContainerBuffering(string aura, params string[] item)
        {
            if (!Me.HasAura(aura))
            {
                WoWItem buffering = FindFirstUsableItemBySpell(item);
                if (buffering != null)
                {
                    buffering.UseContainerItem();
                    Log(buffering);
                }
            }
        }

        public void UseContainerStuff(params string[] item)
        {
            WoWItem stuff = FindFirstUsableItemBySpell(item);
            if (stuff != null)
            {
                stuff.UseContainerItem();
                Log(stuff);
            }
        }

        public WoWItem FindFirstUsableItemBySpell(params string[] spellNames)
        {
            var spellNameHashes = new HashSet<string>(spellNames);

            return (from item in _usableItems
                    let spells = item.ItemSpells
                    where spells.Any(spell => spellNameHashes.Contains(spell.ActualSpell.Name))
                    select item).FirstOrDefault();
        }

        public IEnumerable<WoWItem> GetUsableItems()
        {
            return from item in Me.CarriedItems
                   let spells = item.ItemSpells
                   where
                       item.ItemInfo != null && item.Usable && item.Cooldown <= 0 && spells != null && spells.Count > 0 &&
                       item.ItemInfo.RequiredLevel <= StyxWoW.Me.Level &&
                       spells.Any(spell => spell.IsValid && spell.ActualSpell != null)
                   orderby item.ItemInfo.Level descending
                   select item;
        }
        #endregion
    }

    public partial class UseItem
    {
        private static void Log(WoWItem item)
        {
            Logging.Write(@"[UseItem]: {0}", item.Name);
        }
    }
}